#pragma once

#include <cstdint>
#include <cstdio>
#include <string>
#include <sstream>
#include <iomanip>

inline bool is_leap_year(int year) {
  return (year % 400 == 0) || (year % 100 != 0 && year % 4 == 0);
}

inline int string_to_date(const char *str, int32_t *date) {
  int32_t year;
  int32_t month;
  int32_t day;

  int read = sscanf(str, "%d-%d-%d", &year, &month, &day);
  if (read < 3) {
    LOG_TRACE("unable to parse string as date, s=%s", str);
    return -1;
  }

  if (year < 1 || month < 1 || day < 1) {
    return -1;
  }

  int max_day_of_months[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

  if (is_leap_year(year)) {
    max_day_of_months[2 - 1] = 29;
  }

  if (max_day_of_months[month - 1] < day) {
    return -1;
  }

  *date = year * 10000 + month * 100 + day;  
  return 0;
}

inline std::string date_to_string(int32_t date) {
  int32_t day = date % 100;
  int32_t month = (date / 100) % 100;
  int32_t year = date / 10000;
  std::stringstream buf;
  buf << year << '-' << std::setfill('0') << std::setw(2) << month << '-' << std::setw(2) << day;
  return buf.str();
}